// scripts/deploy_upgradeable_box.js
const {ethers, upgrades} = require('hardhat')

const property = require('../.env.' + [process.env.network])

// specify deploy function
if (!process.env.deploy) {
    process.env.deploy = 'deployContract'
}

// addresses storage
let addrObj = JSON.parse(JSON.stringify(property.addr))

module.exports.print = async () => {
    let arr = []
    for (const key in addrObj) {
        arr.push(key)
    }
    arr.sort()

    for (const i in arr) {
        console.log(arr[i] + ': \'' + addrObj[arr[i]] + '\',')
    }
}

/**
 * deploy contract
 */
module.exports.deployContract = async () => {
    try {
        addrObj.configBaseAddress = await this.deployConfigBase()
        addrObj.psTokenAddress = await this.deployPSToken()
        addrObj.inviterAddress = await this.deployInviter()
        addrObj.exchangeAddress = await this.deployExchange();
        addrObj.idoAddress = await this.deployIDo();
    } catch (e) {
        console.error(e)
    } finally {
        this.print()
    }
}

module.exports.upgradeContract = async () => {

}

module.exports.upgrade = async (contractName, contractAddress) => {
    console.log('upgrade >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>', contractName)
    const contractFactory = await ethers.getContractFactory(contractName)
    const contract = await upgrades.upgradeProxy(contractAddress, contractFactory, {})
    console.log('upgrade:', contract.address)
}

module.exports.deployConfigBase = async () => {
    console.log('deployConfigBase >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
    const ConfigBase = await ethers.getContractFactory('ConfigBase')
    const contract = await upgrades.deployProxy(ConfigBase, [], {})
    await contract.deployed()
    console.log('contractAddress:', contract.address)
    // await contract.setAuth(addrObj.adminAddress, true)
    // await contract.setAuth(addrObj.auth1Address, true)

    // await contract.setConfigUint("tcoinPrice","1000000000000000000")
    // await contract.setConfigUint("poolAmountOneDay","210000000000000000000000");
    // await contract.setConfigNameOf(ethers.utils.toUtf8Bytes("psToken"),addrObj.psTokenAddress);
    // // await contract.setConfigNameOf(ethers.utils.toUtf8Bytes("lpToken"),addrObj.lpTokenAddress);
    // await contract.setConfigNameOf(ethers.utils.toUtf8Bytes("usdtToken"),addrObj.usdtTokenAddress);
    // await contract.setConfigNameOf(ethers.utils.toUtf8Bytes("lpStakePool"),"0xAfB1306976cA6a4Cf55253EE217B50A05394D0F2");   // 挖矿池子
    // await contract.setConfigNameOf(ethers.utils.toUtf8Bytes("idoPool"),"0x0d39b59D2FFBA4a7f703fFb446A28417F6d21e71");       // ido 池子
    // await contract.setConfigNameOf(ethers.utils.toUtf8Bytes("inviterPool"),"0xAfB1306976cA6a4Cf55253EE217B50A05394D0F2");   // 推广 池子
    // r = await contract.setConfigNameOf(ethers.utils.toUtf8Bytes("hfPool"),"0x365669425C26e25aD5deEB947687f4729dDfa551");    // 手续费池子
    // console.log(r);
    return contract.address
}


module.exports.deployAssets = async () => {
    console.log('deployAssets >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
    const args = []
    const Assets = await ethers.getContractFactory('Assets')
    const contract = await upgrades.deployProxy(Assets, args, {})
    await contract.deployed()
    console.log('contractAddress:', contract.address)

    await contract.setAuth(addrObj.adminAddress, true)

    console.log('configBase.setConfigNameOf ---------------------------------')
    const configBase = (await ethers.getContractFactory('ConfigBase')).attach(addrObj.configBaseAddress)
    await configBase.setConfigNameOf(ethers.utils.toUtf8Bytes('assets'), contract.address)

    return contract.address
}

module.exports.deployPSToken = async () => {
    console.log('deployPSToken >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
    const ERC20Token = await ethers.getContractFactory('ERC20Token')
    const args = ['Tcoin', 'Tcoin', 18, 210_000_000]
    const contract = await upgrades.deployProxy(ERC20Token, args, {})
    await contract.deployed()
    console.log('contractAddress:', contract.address)
    
    // console.log('configBase.setConfigNameOf ---------------------------------')
    // const configBase = (await ethers.getContractFactory('ConfigBase')).attach(addrObj.configBaseAddress)
    // await configBase.setConfigNameOf(ethers.utils.toUtf8Bytes('psToken'), contract.address)
    return contract.address
}

module.exports.deployPSTokenUnUpgrade = async () => {
    console.log('deployAssetsConf >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
    const ERC20TokenNotUpgrade = await ethers.getContractFactory('ERC20TokenNotUpgrade')
    const contract = await ERC20TokenNotUpgrade.deploy()
    console.log('contractAddress:', contract.address)

    // console.log('configBase.setConfigNameOf ---------------------------------')
    // const configBase = (await ethers.getContractFactory('ConfigBase')).attach(addrObj.configBaseAddress)
    // await configBase.setConfigNameOf(ethers.utils.toUtf8Bytes('psToken'), contract.address)

    return contract.address
}

module.exports.deployLPToken = async () => {
    console.log('deployLPToken >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
    const ERC20Token = await ethers.getContractFactory('ERC20Token')
    const args = ['Tcoin-LP', 'TCOIN-LP', 18, 210_000_000]
    const contract = await upgrades.deployProxy(ERC20Token, args, {})
    await contract.deployed()
    console.log('contractAddress:', contract.address)
    
    console.log('configBase.setConfigNameOf ---------------------------------')
    const configBase = (await ethers.getContractFactory('ConfigBase')).attach(addrObj.configBaseAddress)
    await configBase.setConfigNameOf(ethers.utils.toUtf8Bytes('lpToken'), contract.address)

    return contract.address
}

module.exports.deployConversion = async () => {
    console.log('deployConversion >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
    const Conversion = await ethers.getContractFactory('Conversion')
    const args = [addrObj.psTokenAddress, addrObj.psTokenAddress]
    const contract = await upgrades.deployProxy(Conversion, args, {})
    await contract.deployed()
    console.log('contractAddress:', contract.address)

    // console.log('setConfig -------------------------------- ')
    // await contract.setConfig(addrObj.configBaseAddress)

    // await contract.setAuth(addrObj.auth1Address, true)

    return contract.address
}

module.exports.deployUSDTToken = async () => {
    console.log('deployPSToken >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
    const ERC20Token = await ethers.getContractFactory('ERC20Token')
    const args = ['USDTTCoin', 'USDTTCoin', 18, 210_000_000]
    const contract = await upgrades.deployProxy(ERC20Token, args, {})
    await contract.deployed()
    console.log('contractAddress:', contract.address)

    console.log('configBase.setConfigNameOf ---------------------------------')
    const configBase = (await ethers.getContractFactory('ConfigBase')).attach(addrObj.configBaseAddress)
    await configBase.setConfigNameOf(ethers.utils.toUtf8Bytes('usdtToken'), contract.address)

    return contract.address
}

module.exports.deployIDo = async () => {
    console.log('deployIDo >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
    const IDo = await ethers.getContractFactory('IDo')
    const args = []
    const contract = await upgrades.deployProxy(IDo, args, {})
    await contract.deployed()
    console.log('contractAddress:', contract.address)

    console.log('setConfig -------------------------------- ')
    await contract.setConfig(addrObj.configBaseAddress)

    await contract.setAuth(addrObj.auth1Address, true)

    return contract.address
}

module.exports.deployInviter = async () => {
    console.log('deployInviter >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
    const Inviter = await ethers.getContractFactory('Inviter')
    const args = []
    const contract = await upgrades.deployProxy(Inviter, args, {})
    await contract.deployed()
    console.log('contractAddress:', contract.address)

    console.log('setConfig -------------------------------- ')
    await contract.setConfig(addrObj.configBaseAddress)

    console.log('configBase.setConfigNameOf ---------------------------------')
    const configBase = (await ethers.getContractFactory('ConfigBase')).attach(addrObj.configBaseAddress)
    await configBase.setConfigNameOf(ethers.utils.toUtf8Bytes('inviter'), contract.address)

    return contract.address
}

module.exports.deployPoolHF = async () => {
    console.log("deployPoolNFT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
    const PoolHF = await ethers.getContractFactory('PoolHF')
    const args = []
    const contract = await upgrades.deployProxy(PoolHF, args, {})
    await contract.deployed()
    console.log('contractAddress:', contract.address)

    console.log('setConfig -------------------------------- ')
    await contract.setConfig(addrObj.configBaseAddress)

    console.log('configBase.setConfigNameOf ---------------------------------')
    const configBase = (await ethers.getContractFactory('ConfigBase')).attach(addrObj.configBaseAddress)
    await configBase.setConfigNameOf(ethers.utils.toUtf8Bytes('PoolHF'), contract.address)

    return contract.address
}

module.exports.deployNFTHero = async () => {
    console.log("deployNFTHero >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
    const args = ["nftHero", "Hero"]
    const NFTHero = await ethers.getContractFactory('NFTHero')
    const contract = await upgrades.deployProxy(NFTHero, args, {})
    await contract.deployed()
    console.log('contractAddress:', contract.address)

    console.log('setConfig -------------------------------- ')
    await contract.setConfig(addrObj.configBaseAddress)

    console.log('configBase.setConfigNameOf ---------------------------------')
    const configBase = (await ethers.getContractFactory('ConfigBase')).attach(addrObj.configBaseAddress)
    await configBase.setConfigNameOf(ethers.utils.toUtf8Bytes('nftHero'), contract.address)

    console.log('PoolHF setAuth ---------------------------------')
    const inviter = (await ethers.getContractFactory('PoolHF')).attach(addrObj.poolHFAddress)
    await inviter.setAuth(contract.address, true)

    return contract.address
}

module.exports.deployNFTBox = async () => {
    console.log("deployNFTBox >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
    const NFTBox = await ethers.getContractFactory('NFTBox')
    const args = []
    const contract = await upgrades.deployProxy(NFTBox, args, {})
    await contract.deployed()
    console.log('contractAddress:', contract.address)

    console.log('setConfig -------------------------------- ')
    await contract.setConfig(addrObj.configBaseAddress)

    console.log('updateStorage -------------------------------- ')
    await contract.updateStorage([[2000,130],[1000,220],[200,1200],[50,4000],[10,8000]]);

    console.log('NFTHero setAuth ---------------------------------')
    const nftHero = (await ethers.getContractFactory('NFTHero')).attach(addrObj.nftHeroAddress)
    await nftHero.setAuth(contract.address, true)

    console.log('Assets setAuth ---------------------------------')
    const assets = (await ethers.getContractFactory('Assets')).attach(addrObj.assetsAddress)
    await assets.setAuth(contract.address, true)

    console.log('Inviter setAuth ---------------------------------')
    const inviter = (await ethers.getContractFactory('Inviter')).attach(addrObj.inviterAddress)
    await inviter.setAuth(contract.address, true)

    console.log('PoolHF setAuth ---------------------------------')
    const poolHF = (await ethers.getContractFactory('PoolHF')).attach(addrObj.poolHFAddress)
    await poolHF.setAuth(contract.address, true)
    
    return contract.address
}

module.exports.deployPoolLP = async () => {
    console.log("deployPoolLP >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
    const PoolLP = await ethers.getContractFactory('PoolLP')
    const args = []
    const contract = await upgrades.deployProxy(PoolLP, args, {})
    await contract.deployed()
    console.log('contractAddress:', contract.address)

    console.log('setConfig -------------------------------- ')
    await contract.setConfig(addrObj.configBaseAddress)

    console.log('configBase.setConfigNameOf ---------------------------------')
    const configBase = (await ethers.getContractFactory('ConfigBase')).attach(addrObj.configBaseAddress)
    await configBase.setConfigNameOf(ethers.utils.toUtf8Bytes('PoolLP'), contract.address)
    
    console.log('Inviter setAuth ---------------------------------')
    const inviter = (await ethers.getContractFactory('Inviter')).attach(addrObj.inviterAddress)
    await inviter.setAuth(contract.address, true)

    return contract.address
}

module.exports.deployPoolNFT = async () => {
    console.log("deployPoolNFT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
    const PoolNFT = await ethers.getContractFactory('PoolNFT')
    const args = []
    const contract = await upgrades.deployProxy(PoolNFT, args, {})
    await contract.deployed()
    console.log('contractAddress:', contract.address)

    console.log('setConfig -------------------------------- ')
    await contract.setConfig(addrObj.configBaseAddress)

    console.log('configBase.setConfigNameOf ---------------------------------')
    const configBase = (await ethers.getContractFactory('ConfigBase')).attach(addrObj.configBaseAddress)
    await configBase.setConfigNameOf(ethers.utils.toUtf8Bytes('PoolNFT'), contract.address)
    
    console.log('Inviter setAuth ---------------------------------')
    const inviter = (await ethers.getContractFactory('Inviter')).attach(addrObj.inviterAddress)
    await inviter.setAuth(contract.address, true)

    return contract.address
}

module.exports.deployPoolNode = async () => {
    console.log("deployPoolNode >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
    const PoolNode = await ethers.getContractFactory('PoolNode')
    const args = []
    const contract = await upgrades.deployProxy(PoolNode, args, {})
    await contract.deployed()
    console.log('contractAddress:', contract.address)

    console.log('setConfig -------------------------------- ')
    await contract.setConfig(addrObj.configBaseAddress)

    console.log('configBase.setConfigNameOf ---------------------------------')
    const configBase = (await ethers.getContractFactory('ConfigBase')).attach(addrObj.configBaseAddress)
    await configBase.setConfigNameOf(ethers.utils.toUtf8Bytes('PoolNode'), contract.address)
    
    console.log('Inviter setAuth ---------------------------------')
    const inviter = (await ethers.getContractFactory('Inviter')).attach(addrObj.inviterAddress)
    await inviter.setAuth(contract.address, true)

    await contract.setAuth(addrObj.inviterAddress, true);

    return contract.address
}

module.exports.deployAirdrop = async () => {
    console.log("deployAirdrop >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
    const Airdrop = await ethers.getContractFactory('Airdrop')
    const args = []
    const contract = await upgrades.deployProxy(Airdrop, args, {})
    await contract.deployed()
    console.log('contractAddress:', contract.address)

    console.log('setConfig -------------------------------- ')
    await contract.setConfig(addrObj.configBaseAddress)

    console.log('Assets setAuth ---------------------------------')
    const assets = (await ethers.getContractFactory('Assets')).attach(addrObj.assetsAddress)
    await assets.setAuth(contract.address, true)
}

module.exports.deployExchange = async () => {
    console.log('deployExchange >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
    const Exchange = await ethers.getContractFactory('Exchange')
    const args = []
    console.log('inviterAddress:', addrObj.inviterAddress)

    const contract = await upgrades.deployProxy(Exchange, args, {})
    await contract.deployed()
    console.log('contractAddress:', contract.address)

    console.log('setConfig -------------------------------- ')
    await contract.setConfig(addrObj.configBaseAddress)

    console.log('configBase.setConfigNameOf ---------------------------------')
    const configBase = (await ethers.getContractFactory('ConfigBase')).attach(addrObj.configBaseAddress)
    await configBase.setConfigNameOf(ethers.utils.toUtf8Bytes('exchange'), contract.address)

    console.log('Inviter setAuth ---------------------------------')
    const inviter = (await ethers.getContractFactory('Inviter')).attach(addrObj.inviterAddress)
    await inviter.setAuth(contract.address, true)

    console.log('NFTHero setAuth ---------------------------------')
    const nftHero = (await ethers.getContractFactory('NFTHero')).attach(addrObj.nftHeroAddress)
    await nftHero.setAuth(contract.address, true)
1
    console.log('Assets setAuth ---------------------------------')
    const assets = (await ethers.getContractFactory('Assets')).attach(addrObj.assetsAddress)
    await assets.setAuth(contract.address, true)

    console.log('PoolHF setAuth ---------------------------------')
    const poolHF = (await ethers.getContractFactory('PoolHF')).attach(addrObj.poolHFAddress)
    await poolHF.setAuth(contract.address, true)


    return contract.address
}

module.exports.deployCheck = async () => {
    console.log('deployCheck >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
    const Check = await ethers.getContractFactory('Check')
    const args = []

    const contract = await upgrades.deployProxy(Check, args, {})
    await contract.deployed()
    console.log('contractAddress:', contract.address)

    console.log('setConfig -------------------------------- ')
    await contract.setConfig(addrObj.configBaseAddress)

    await contract.setAuth(addrObj.auth1Address, true)
}

module.exports.TokenToolLock = async () => {
    console.log('deployTokenToolLock >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
    const TokenToolLock = await ethers.getContractFactory('TokenToolLock')

    const contract = await TokenToolLock.deploy()
    console.log('contractAddress:', contract.address)
}

this[process.env.deploy]()
